import 'package:flutter/material.dart';

// 评分星星的封装
class JKStarRating extends StatefulWidget {
  /* 分数 */
  final double rating;
  /* 满分是多少分 */
  final double maxRating;
  /* 准备有几颗星 */
  final int starCount;
  /* 展示的星大小 */
  final double starSize;
  /* 未选中星的颜色 */
  final Color unSelectColor;
  /* 选中星的颜色 */
  final Color selectedColor;
  /* 未选中星的图片 */
  final Widget unSelectImage;
  /* 选中星的图片 */
  final Widget selectedImage;

  JKStarRating({
    @required this.rating,
    this.maxRating = 10,
    this.starCount = 5,
    this.starSize = 30,
    this.unSelectColor = const Color(0xffbbbbbb),
    this.selectedColor = const Color(0xffff0000),
    Widget unSelectImage,
    Widget selectedImage
  }): unSelectImage = unSelectImage ?? Icon(Icons.star_border, color: unSelectColor, size: starSize),
        selectedImage = selectedImage ?? Icon(Icons.star, color: selectedColor, size: starSize);

  @override
  _JKStarRatingState createState() => _JKStarRatingState();
}

class _JKStarRatingState extends State<JKStarRating> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Row(mainAxisSize: MainAxisSize.min, children: buildUnSelectedStar()),
        Row(mainAxisSize: MainAxisSize.min, children: buildSelectedStar())
      ],
    );
  }

  List<Widget> buildUnSelectedStar() {
    return List.generate(widget.starCount, (index) {
      return widget.unSelectImage;
    });
  }

  List<Widget> buildSelectedStar() {
    // 1.创建stars
    List<Widget> stars = [];
    final star = widget.selectedImage;

    // 2.构建满填充的star
    // 每个星星占多少分
    double oneValue = widget.maxRating / widget.starCount;
    // 根据分数计算满星的个数, 向下取整，比如 3.5 取值 3
    int entireCount = (widget.rating / oneValue).floor();
    for (var i = 0; i < entireCount; i++) {
      stars.add(star);
    }

    // 3.获取部分星星
    // 不满星所占据的一个星宽度
    double leftWidth = (widget.rating / oneValue - entireCount) * widget.starSize;
    // 不满星的 widget
    final halfStar = ClipRect(
      clipper: JKStarClipper(leftWidth),
      child: star,
    );
    stars.add(halfStar);

    // 超出满分按满分计算
    if (stars.length > widget.starCount) {
      return stars.sublist(0, widget.starCount);
    }

    return stars;
  }
}

class JKStarClipper extends CustomClipper<Rect> {
  double width;

  JKStarClipper(this.width);

  // 裁剪
  @override
  Rect getClip(Size size) {
    return Rect.fromLTRB(0, 0, width, size.height);
  }

  // 重新裁剪
  @override
  bool shouldReclip(JKStarClipper oldClipper) {
    // 不相等就重新裁剪
    return oldClipper.width != width;
  }

}